package com.example.netty.netty.TCPExample;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.ScheduledFuture;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

//需要继承一个HandlerAdapter（有很多个）
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("上下文信息："+ctx);
        //这是netty包的，不是NIO的bytebuffer，进行了二次分装性能要高一些
        ByteBuf byteBuf = (ByteBuf) msg;
        System.out.println("接收到信息："+byteBuf.toString(CharsetUtil.UTF_8));
        System.out.println("客户端地址为："+ctx.channel().remoteAddress());

        //如果有非常耗时的逻辑，又不想阻塞当前线程可以通过ctx获取管道，再获取NioEventLoop提交taskQueue，
        // 用另一个线程来异步执行,taskQueue里面只有一个线程，会按顺序执行提交的任务
        //提交任务一
        ctx.channel().eventLoop().execute(()->{
            //模拟耗时逻辑
            try {
                Thread.sleep(5*1000);
                ctx.pipeline().writeAndFlush(Unpooled.copiedBuffer("!!!finish async task1....",CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        System.out.println("已提交异步任务1。。。。");
        //提交任务二
        ctx.channel().eventLoop().execute(()->{
            //模拟耗时逻辑
            try {
                Thread.sleep(5*1000);
                ctx.writeAndFlush(Unpooled.copiedBuffer("finish async task2....",CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        System.out.println("已提交异步任务2。。。。");
        //提交定时任务三:加入的任务队列区别于普通人物队列
        ctx.channel().eventLoop().schedule(()->{
            ctx.writeAndFlush(Unpooled.copiedBuffer("finish async scheduleTask3....",CharsetUtil.UTF_8));
        },5, TimeUnit.SECONDS);
        System.out.println("已提交异步定时任务3。。。。");
        //循环执行
        ScheduledFuture<?> scheduledFuture = ctx.channel().eventLoop().scheduleAtFixedRate(() -> {
            ctx.writeAndFlush(Unpooled.copiedBuffer("finish async scheduleTask4....", CharsetUtil.UTF_8));
        }, 5, 5, TimeUnit.SECONDS);
        System.out.println("已提交异步定时任务4。。。。");

        ctx.channel().eventLoop().schedule(()->{
            System.out.println("结束任务4");
            scheduledFuture.cancel(false);
        },30,TimeUnit.SECONDS);

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //读取完成后触发，一般用于数据返回
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello,client...",CharsetUtil.UTF_8))
                .addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        System.out.println("消息发送成功");
                    }
                });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //发生异常时触发，一般要关闭通道
        ctx.close();
    }
}
